package com.videoStream.video.push;


import com.videoStream.video.pojo.CameraPojo;
import com.videoStream.video.pojo.Config;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FFmpegLogCallback;
import org.bytedeco.javacv.Frame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import java.io.File;


/**
 * @Title RtmpPush.java
 * @description javacv推数据帧
 * @time 2020年3月17日 下午2:32:42
 * @author wuguodong
 **/
public class CameraPush {
	private final static Logger logger = LoggerFactory.getLogger(CameraPush.class);
	// 配置类
	private static Config config;

	// 通过applicationContext上下文获取Config类
	public static void setApplicationContext(ApplicationContext applicationContext) {
		config = applicationContext.getBean(Config.class);
	}

	private CameraPojo pojo;// 设备信息
	private FFmpegFrameRecorder recorder;// 解码器
	private FFmpegFrameGrabber grabber;// 采集器
	private int err_index = 0;// 推流过程中出现错误的次数
	private int exitcode = 0;// 退出状态码：0-正常退出;1-手动中断;
	private double framerate = 0;// 帧率

	public void setExitcode(int exitcode) {
		this.exitcode = exitcode;
	}

	public int getExitcode() {
		return exitcode;
	}

	public CameraPush(CameraPojo cameraPojo) {
		this.pojo = cameraPojo;
	}

	/**
	 * @Title: release
	 * @Description:资源释放
	 * @return void
	 **/
	public void release() {
		try {
			grabber.stop();
			grabber.close();
			if (recorder != null) {
				recorder.stop();
				recorder.release();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @Title: push
	 * @Description:推送视频流数据包
	 * @return void
	 **/
	public void push() {
		//删除m3u8目录

		try {
			avutil.av_log_set_level(avutil.AV_LOG_INFO);
			FFmpegLogCallback.set();
			grabber = new FFmpegFrameGrabber(pojo.getRtsp());
			grabber.setOption("rtsp_transport", "tcp");
			// 设置采集器构造超时时间
			grabber.setOption("stimeout", "2000000");
			if ("sub".equals(pojo.getStream())) {
				grabber.start(config.getSub_code());
			} else if ("main".equals(pojo.getStream())) {
				grabber.start(config.getMain_code());
			} else {
				grabber.start(config.getMain_code());
			}

			// 部分监控设备流信息里携带的帧率为9000，如出现此问题，会导致dts、pts时间戳计算失败，播放器无法播放，故出现错误的帧率时，默认为25帧
			if (grabber.getFrameRate() > 0 && grabber.getFrameRate() < 100) {
				framerate = grabber.getFrameRate();
			} else {
				framerate = 25.0;
			}
			int width = grabber.getImageWidth();
			int height = grabber.getImageHeight();
			// 若视频像素值为0，说明拉流异常，程序结束
			if (width == 0 && height == 0) {
				logger.error(pojo.getRtsp() + "  拉流异常！");
				grabber.stop();
				grabber.close();
				release();
				return;
			}
			recorder = new FFmpegFrameRecorder(pojo.getM3u8(),grabber.getImageWidth(),grabber.getImageHeight(),0);
                /*//视频帧率
                record.setFrameRate(grabber.getFrameRate());
                //编码
                record.setVideoCodec(avcodec.AV_CODEC_ID_H264);
                record.setFormat("mp4");*/
			recorder.setFormat("hls");
			recorder.setOption("hls_time", "5");
			recorder.setOption("hls_list_size", "5");
			recorder.setOption("hls_flags", "delete_segments");
			recorder.setOption("hls_delete_threshold", "1");
			recorder.setOption("hls_segment_type", "mpegts");
			recorder.setOption("hls_segment_filename",pojo.getM3u8FileTemplate() );
			//record.setOption("hls_key_info_file", "http://localhost:8080/preview/");

			// http属性
			recorder.setOption("method", "POST");

			recorder.setFrameRate(25);
			recorder.setGopSize(2 * 25);
			recorder.setVideoQuality(1.0);
			recorder.setVideoBitrate(10 * 1024);
			recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
			recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
			recorder.start();

			Frame frame;
                /*while (((System.currentTimeMillis()-startTime) <=30000) &&(frame=grabber.grab()) != null){
                    if(frame.image != null){
                        record.record(frame);
                    }
                }*/
			while ((frame=grabber.grab()) != null){
				if(frame.image != null){
					recorder.record(frame);
					//中断推流
					if (exitcode == 1) {
						break;
					}
				}
			}
			System.out.println("执行结束");
			grabber.stop();
			recorder.stop();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
		} finally {
			release();
			logger.info("推流结束 设备信息：[ip:" + pojo.getIp() + " channel:" + pojo.getChannel() + " stream:"
					+ pojo.getStream() + " starttime:" + pojo.getStarttime() + " endtime:" + pojo.getEndtime()
					+ " rtsp:" + pojo.getRtsp() + " url:" + pojo.getUrl() + "]");
		}
	}
}